/**
* Copyright (C) 2018-2020
* All rights reserved, Designed By www.yixiang.co
* ע�⣺
* �����Ϊwww.yixiang.co�������ƣ�δ�����򲻵�ʹ��
* �����ɻ��ȫ��Դ���루��ֹת���������ϴ������ơ�github�ȿ�Դƽ̨��
* һ�����ֵ��á��������Ϊ����׷���������Σ�����Ը�
*/
package co.yixiang.modules.system.rest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import co.yixiang.dozer.service.IGenerator;
import co.yixiang.enums.ShopCommonEnum;
import co.yixiang.exception.BadRequestException;
import co.yixiang.modules.aop.ForbidSubmit;
import co.yixiang.modules.order.service.YxStoreOrderService;
import co.yixiang.modules.system.domain.User;
import co.yixiang.modules.system.service.dto.UserDto;
import co.yixiang.modules.user.domain.ManagementAwardData;
import co.yixiang.modules.user.domain.MonthlyManagementAward;
import co.yixiang.modules.user.domain.YxUser;
import co.yixiang.modules.user.service.ManagementAwardDataService;
import co.yixiang.modules.user.service.MonthlyManagementAwardDetailService;
import co.yixiang.modules.user.service.MonthlyManagementAwardService;
import co.yixiang.modules.user.service.YxUserService;
import co.yixiang.modules.user.service.dto.MonthlyManagementAwardDto;
import co.yixiang.modules.user.service.dto.MonthlyManagementAwardQueryCriteria;
import co.yixiang.tools.domain.VerificationCode;
import co.yixiang.utils.SecurityUtils;
import co.yixiang.utils.YshopConstant;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import co.yixiang.logging.aop.log.Log;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import co.yixiang.domain.PageResult;
/**
* @author lsh
* @date 2021-05-12
*/
@AllArgsConstructor
@Api(tags = "monthlyManagementAward")
@RestController
@RequestMapping("/api")
public class MonthlyManagementAwardController {

    private final MonthlyManagementAwardService monthlyManagementAwardService;
    private final YxUserService yxUserService;
    private final YxStoreOrderService storeOrderService;
    private final ManagementAwardDataService managementAwardDataService;
    private final MonthlyManagementAwardDetailService monthlyManagementAwardDetailService;
    private final IGenerator generator;


    @Log("导出数据")
    @ApiOperation("导出数据")
    @GetMapping(value = "/monthlyManagementAward/download")
    @PreAuthorize("hasAnyRole('admin','YXSYSTEMCONFIG_ALL','YXSYSTEMCONFIG_SELECT')")
    public void download(HttpServletResponse response, MonthlyManagementAwardQueryCriteria criteria) throws IOException {
        monthlyManagementAwardService.download(generator.convert(monthlyManagementAwardService.queryAll(criteria), MonthlyManagementAwardDto.class), response);
    }

    @GetMapping(value = "/monthlyManagementAward")
    @Log("查询monthlyManagementAward")
    @ApiOperation("查询monthlyManagementAward")
    @PreAuthorize("hasAnyRole('admin','YXSYSTEMCONFIG_ALL','YXSYSTEMCONFIG_SELECT')")
    public ResponseEntity<PageResult<MonthlyManagementAwardDto>> getMonthlyManagementAwards(MonthlyManagementAwardQueryCriteria criteria, Pageable pageable){
        return new ResponseEntity<>(monthlyManagementAwardService.queryAll(criteria,pageable),HttpStatus.OK);
    }

    @PostMapping(value = "/monthlyManagementAward")
    @Log("新增monthlyManagementAward")
    @ApiOperation("新增monthlyManagementAward")
    public ResponseEntity<Object> create(@Validated @RequestBody MonthlyManagementAward resources){
        return new ResponseEntity<>(monthlyManagementAwardService.save(resources),HttpStatus.CREATED);
    }

    @PutMapping(value = "/monthlyManagementAward")
    @Log("修改monthlyManagementAward")
    @ApiOperation("修改monthlyManagementAward")
    public ResponseEntity<Object> update(@Validated @RequestBody MonthlyManagementAward resources){
        monthlyManagementAwardService.updateById(resources);
         return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @Log("删除monthlyManagementAward")
    @ApiOperation("删除monthlyManagementAward")
    @DeleteMapping(value = "/monthlyManagementAward/{id}")
    public ResponseEntity<Object> delete(@PathVariable Integer id) {
            monthlyManagementAwardService.removeById(id);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @Log("自动生成月管理奖数据")
    @ApiOperation("自动生成月管理奖数据")
    @PostMapping(value = "/autoManagementAward/{month}")
    public ResponseEntity<Object> autoManagementAward(@PathVariable String month){
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM");
        String startDay = month;
        Date date;
        try {
            date = df.parse(startDay);
        }catch (ParseException e){
            e.printStackTrace();
            date=new Date();
        }
        int dateOne= getYearMonth(date);
        int sysDate = getYearMonth(new Date());
        if(dateOne>=sysDate){
            return new ResponseEntity<>(HttpStatus.IM_USED);
        }else{
            List<MonthlyManagementAward> mmaList = monthlyManagementAwardService.list(Wrappers.<MonthlyManagementAward>lambdaQuery()
                    .eq(MonthlyManagementAward::getMonth, month));
            List<MonthlyManagementAward> mainList =new ArrayList<MonthlyManagementAward>();

            if (mmaList.size()<=0) {
                List<HashMap<String,Object>> detailList=monthlyManagementAwardDetailService.getMonthData(month);
                if(detailList.size()>0){
                    List<ManagementAwardData> dataList =managementAwardDataService.list();
                    if(dataList.size()>0){
                        for(int i=0;i<detailList.size();i++) {
                            Map item = detailList.get(i);
                            String uid = item.get("uid").toString();
                            String level = item.get("level").toString();
                            String totalSum = item.get("total_sum").toString();
                            YxUser user = yxUserService.getById(Long.valueOf(uid));
                            YxUser parentUser = new YxUser();
                            MonthlyManagementAward main = new MonthlyManagementAward();
                            main.setLevel(user.getLevel());
                            main.setMonth(month);
                            main.setUid(user.getUid());
                            main.setUserPhone(user.getPhone());
                            main.setHeadimgurl(user.getAvatar());
                            main.setTotalSum(new BigDecimal(totalSum));
                            if (user.getSpreadUid().intValue() != 0) {
                                parentUser = yxUserService.getById(user.getSpreadUid());
                                main.setParentId(parentUser.getUid());
                                main.setParentUserPhone(parentUser.getPhone());
                                main.setParentNickname(parentUser.getNickname());
                                main.setParentHeadimgurl(parentUser.getAvatar());
                            }
                            BigDecimal awardSum =new BigDecimal("0");
                            for(int m=0;m<dataList.size();m++){
                                ManagementAwardData data =dataList.get(m);
                                if (new BigDecimal(totalSum).compareTo(data.getUseMinPrice()) > 0 && new BigDecimal(totalSum).compareTo(data.getUseMaxPrice()) != 1) {
                                    awardSum =new BigDecimal(totalSum).multiply(new BigDecimal(data.getShareRatio()).multiply(new BigDecimal("0.01")));
                                    break;
                                }
                            }
                            main.setReceivableSum(awardSum);
                            mainList.add(main);
                        }
                        monthlyManagementAwardService.saveBatch(mainList);
                        List<MonthlyManagementAward> mList = monthlyManagementAwardService.list(Wrappers.<MonthlyManagementAward>lambdaQuery()
                                .eq(MonthlyManagementAward::getMonth, month));
                        List<MonthlyManagementAward> updateList =new ArrayList<MonthlyManagementAward>();
                        if(mList.size()>0){
                            for(int i=0;i<mList.size();i++){
                                MonthlyManagementAward award =mList.get(i);
                                List<MonthlyManagementAward> childList = monthlyManagementAwardService.list(Wrappers.<MonthlyManagementAward>lambdaQuery()
                                        .eq(MonthlyManagementAward::getMonth, month)
                                        .eq(MonthlyManagementAward::getParentId, award.getUid()));
                                BigDecimal receivableSum = BigDecimal.ZERO;
                                if(childList.size()>0){
                                    for(int j=0;j<childList.size();j++){
                                        MonthlyManagementAward childAward =childList.get(j);
                                        receivableSum =receivableSum.add(childAward.getReceivableSum());
                                    }
                                }
                                BigDecimal receiptsSum =award.getReceivableSum().subtract(receivableSum);
                                if(receiptsSum.compareTo(BigDecimal.ZERO) ==0){
                                    award.setStatus(1);
                                }
                                award.setReceiptsSum(receiptsSum);
                                updateList.add(award);
                            }



                            monthlyManagementAwardService.saveOrUpdateBatch(updateList);
                        }
                        /*List<YxUser> userChildList = yxUserService.list(Wrappers.<YxUser>lambdaQuery()
                                //.eq(YxUser::getLevel, 5)
                                .eq(YxUser::getSpreadUid, user.getUid()));


                            BigDecimal parentSum =storeOrderService.monthAwardSum(user.getUid(),month);
                            BigDecimal awardSum =new BigDecimal("0");
                            for(int m=0;m<dataList.size();m++){
                                ManagementAwardData data =dataList.get(m);
                                if (parentSum.compareTo(data.getUseMinPrice()) > 0 && parentSum.compareTo(data.getUseMaxPrice()) != 1) {
                                    awardSum =parentSum.multiply(new BigDecimal(data.getShareRatio()).multiply(new BigDecimal("0.01")));
                                    //MonthlyManagementAward mma = new MonthlyManagementAward();

                                    //mma.setReceiptsSum(childAwardSum);
                                    //monthlyManagementAwardService.save(mma);
                                    break;
                                }
                            }
                            if (ObjectUtil.isNull(parentUser)) {
                                mma =mma.builder()
                                        .level(user.getLevel())
                                        .month(month)
                                        .uid(user.getUid())
                                        .userPhone(user.getPhone())
                                        .nickname(user.getNickname())
                                        .headimgurl(user.getAvatar())
                                        .totalSum(parentSum)
                                        .receivableSum(awardSum)
                                        .build();
                            }else{
                                mma =mma.builder()
                                        .level(user.getLevel())
                                        .month(month)
                                        .uid(user.getUid())
                                        .userPhone(user.getPhone())
                                        .nickname(user.getNickname())
                                        .headimgurl(user.getAvatar())
                                        .parentId(parentUser.getUid())
                                        .parentUserPhone(parentUser.getPhone())
                                        .parentNickname(parentUser.getNickname())
                                        .parentHeadimgurl(parentUser.getAvatar())
                                        .totalSum(parentSum)
                                        .receivableSum(awardSum)
                                        .build();
                            }

                            List<YxUser> userChildList = yxUserService.list(Wrappers.<YxUser>lambdaQuery()
                                    //.eq(YxUser::getLevel, 5)
                                    .eq(YxUser::getSpreadUid, user.getUid()));
                            BigDecimal childAwardSum =new BigDecimal("0");
                            if(userChildList.size()>0){
                                for(int j=0;j<userChildList.size();j++){
                                    YxUser childUser =userChildList.get(j);
                                    BigDecimal childSum =storeOrderService.monthAwardSum(childUser.getUid(),month);
                                    for(int m=0;m<dataList.size();m++){
                                        ManagementAwardData data =dataList.get(m);
                                        if (childSum.compareTo(data.getUseMinPrice()) > 0 && childSum.compareTo(data.getUseMaxPrice()) != 1) {
                                            childAwardSum =childAwardSum.add(childSum.multiply(new BigDecimal(data.getShareRatio()).multiply(new BigDecimal("0.01"))));
                                            break;
                                        }
                                    }
                                }
                            }
                            BigDecimal receiptsSum =awardSum.subtract(childAwardSum);
                            if(receiptsSum.compareTo(BigDecimal.ZERO) ==0){
                                mma.setStatus(1);
                            }
                            mma.setReceiptsSum(receiptsSum);
                            monthlyManagementAwardService.save(mma);
                        }*/
                    }
                }
                return new ResponseEntity<>(HttpStatus.OK);
            }else{
                return new ResponseEntity<>(HttpStatus.IM_USED);
            }
        }


    }

    @ForbidSubmit
    @ApiOperation(value = "是否让用户可见状态")
    @PostMapping(value = "/monthlyManagementAward/onStatus/{id}")
    public ResponseEntity onStatus(@PathVariable Long id,@RequestBody String jsonStr){
        JSONObject jsonObject = JSON.parseObject(jsonStr);
        Integer status = jsonObject.getInteger("status");
        if(ShopCommonEnum.IS_STATUS_1.getValue().equals(status)){
            status = ShopCommonEnum.IS_STATUS_0.getValue();
        }else{
            status = ShopCommonEnum.IS_STATUS_1.getValue();
        }
        MonthlyManagementAward mma = monthlyManagementAwardService.getById(id);
        mma.setIsOpen(status);
        monthlyManagementAwardService.updateById(mma);
        return new ResponseEntity(HttpStatus.OK);
    }

    @ForbidSubmit
    @ApiOperation(value = "审核通过生成月管理奖")
    @PostMapping(value = "/monthlyManagementAward/approve/{id}")
    public ResponseEntity approve(@PathVariable Long id){
        MonthlyManagementAward mma = monthlyManagementAwardService.getById(id);
        //mma.setStatus(1);
        monthlyManagementAwardService.doApprove(mma);
        return new ResponseEntity(HttpStatus.OK);
    }

    public static int getYearMonth(Date date){
        //传入日期
        Calendar calder = Calendar.getInstance();
        calder.setTime(date);//设置时间
        int year = calder.get(Calendar.YEAR);//获取年份
        int month=calder.get(Calendar.MONTH);//获取月份
        //返回年份乘以100加上月份的值，因为月份最多2位数，
        // 所以年份乘以100可以获取一个唯一的年月数值
        return year*100+month;
    }
}
